#include "wc3main.h"
#include "Extern_global_Variable.h"

THandlerCallbacks::THandlerCallbacks()
{
	pFirstElement = NULL;
	pCurrentElement = NULL;
	pLastElement = NULL;
	vQ_Elements = 0;
};

THandlerCallbacks * THandlerCallbacks::Create()
{
	return new THandlerCallbacks;
}

void THandlerCallbacks::Destroy()
{
	delete this;
}

void THandlerCallbacks::Add(THandlerCallback * ACallback)
{
	tList* vNewElement = new tList;
	vNewElement->pElement = ACallback;
	if (pFirstElement == NULL && pLastElement == NULL)
	{
		vNewElement->pForerunner_Element = NULL;
		vNewElement->pNext_Element = NULL;
		vNewElement->vN_Element = 0;
		vQ_Elements = 1;
		pFirstElement = vNewElement;
		pLastElement = vNewElement;
	}
	else if(pFirstElement != NULL && pLastElement != NULL)
	{
		vNewElement->vN_Element = pLastElement->vN_Element + 1;
		vQ_Elements++;
		vNewElement->pForerunner_Element = pLastElement;
		vNewElement->pNext_Element = NULL;
		pLastElement = vNewElement;
	}
}

THandlerCallback * THandlerCallbacks::GetFirstElement()
{
	if (pFirstElement == NULL)
	{
		return NULL;
	}
	pCurrentElement = pFirstElement;
	return pCurrentElement->pElement;
}

THandlerCallback * THandlerCallbacks::GetNextElement()
{
	if (pCurrentElement && pCurrentElement->pNext_Element)
	{
		pCurrentElement = pCurrentElement->pNext_Element;
		return pCurrentElement->pElement;
	}
	return NULL;
}

procedure wc3main_SubscribeOnInit(THandlerCallback * ACallback)
{
	if (InitHandlers == NULL) return;
	InitHandlers->Add(ACallback);
}

procedure NotifyInitHandlers()
{
	if (InitHandlers == NULL) return;
	THandlerCallback (*Callback)(void);
	Callback = (THandlerCallback (*)(void))InitHandlers->GetFirstElement();
	while (Callback)
	{
		Callback();
		Callback = (THandlerCallback (*)(void))InitHandlers->GetNextElement();
	}
}

procedure wc3main_SubscribeOnInitDone(THandlerCallback * ACallback)
{
	if (InitDoneHandlers == NULL) return;
	InitDoneHandlers->Add(ACallback);
}

procedure NotifyInitDoneHandlers()
{
	if (InitDoneHandlers == NULL) return;
	THandlerCallback (*Callback)(void);
	Callback = (THandlerCallback (*)(void))InitDoneHandlers->GetFirstElement();
	while (Callback)
	{
		Callback();
		Callback = (THandlerCallback (*)(void))InitDoneHandlers->GetNextElement();
	}
}

procedure wc3main_Init(HMODULE AGameDll)
{
	GameDll = AGameDll;
	NotifyInitHandlers();
	NotifyInitDoneHandlers();
}

void wc3main_initialization()
{
	InitHandlers = THandlerCallbacks::Create();
	InitDoneHandlers = THandlerCallbacks::Create();
}
void wc3main_finalization()
{
	InitHandlers->Destroy();
	InitDoneHandlers->Destroy();
}

















